From e11983c21f2cb64a21816d2a28219b57652c16a9 Mon Sep 17 00:00:00 2001 From: "kaf24@freefall.cl.cam.ac.uk" Date: Fri, 10 Sep 2004 00:27:16 +0000 Subject: [PATCH] bitkeeper revision 1.1159.1.146 (4140f4e4MoMfo8OhzKj1hieTq2id2A) Allow a p.t. to be mapped at multiple different virtual addresses. This is a pretty benign situation right now (although writable pagetables will fail, exiting the domain). In future it may well cause significant slowdown to writable pagetables and/or shadow pagetables. So beware!! --- xen/arch/x86/memory.c | 27 +++++++++++++++++---------- xen/include/asm-x86/mm.h | 5 ++++- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/xen/arch/x86/memory.c b/xen/arch/x86/memory.c index 640181a6cc..bae38bb04d 100644 --- a/xen/arch/x86/memory.c +++ b/xen/arch/x86/memory.c @@ -913,10 +913,9 @@ int get_page_type(struct pfn_info *page, u32 type) } else if ( unlikely((x & PGT_va_mask) != (type & PGT_va_mask)) ) { - /* The va backpointer wasn't mutable, and is different. */ - MEM_LOG("Unexpected va backpointer (saw %08x != exp %08x)" - " for pfn %08lx\n", x, type, page_to_pfn(page)); - return 0; + /* This table is potentially mapped at multiple locations. */ + nx &= ~PGT_va_mask; + nx |= PGT_va_unknown; } } else if ( unlikely(!(x & PGT_validated)) ) @@ -1786,12 +1785,21 @@ int ptwr_do_page_fault(unsigned long addr) page = &frame_table[pfn]; if ( (page->u.inuse.type_info & PGT_type_mask) == PGT_l1_page_table ) { - pl2e = &linear_l2_table[(page->u.inuse.type_info & - PGT_va_mask) >> PGT_va_shift]; + u32 va_mask = page->u.inuse.type_info & PGT_va_mask; + + /* + * XXX KAF: This version of writable pagetables doesn't need + * to know the back pointer at all, as it is unnecessary to be + * unlinking the page table --- FIXME! + */ + if ( unlikely(va_mask >= PGT_va_unknown) ) + domain_crash(); + va_mask >>= PGT_va_shift; + + pl2e = &linear_l2_table[va_mask]; PTWR_PRINTK(PP_ALL, ("page_fault on l1 pt at va %08lx, pt for %08x" ", pfn %08lx\n", addr, - ((page->u.inuse.type_info & PGT_va_mask) >> - PGT_va_shift) << L2_PAGETABLE_SHIFT, pfn)); + va_mask << L2_PAGETABLE_SHIFT, pfn)); if ( l2_pgentry_val(*pl2e) >> PAGE_SHIFT != pfn ) { @@ -1832,8 +1840,7 @@ int ptwr_do_page_fault(unsigned long addr) nl2e = mk_l2_pgentry((l2_pgentry_val(*pl2e) & ~_PAGE_PRESENT)); update_l2e(pl2e, *pl2e, nl2e); - ptwr_info[cpu].disconnected_pteidx = - (page->u.inuse.type_info & PGT_va_mask) >> PGT_va_shift; + ptwr_info[cpu].disconnected_pteidx = va_mask; PTWR_PRINTK(PP_A, ("[A] now pl2e %p l2e %08lx " "taf %08x/%08x\n", pl2e, l2_pgentry_val(*pl2e), diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index 50d5988329..3a4db629ca 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -77,7 +77,10 @@ struct pfn_info /* The 10 most significant bits of virt address if this is a page table. */ #define PGT_va_shift 17 #define PGT_va_mask (((1<<10)-1)<